/*
 * Get the initial population which includes 10 feasible solutions(individuals).
 * Do the crossover operation to the first two solutions;
 * Do the crossover operation to the random two solutions;
 * Do the mutation operation to the third solutions,
 * until there is no better solution can be found within 10 times' feasible iterations,
 * at this time, if the remaining energy is above 500,
 * do the small exploration, else do the big exploration;
 * if within 10 times' feasible exploring iterations, there is no better solution can be
 * found, jump out the exploring, else do the crossover to the better solution.
 * If remaining energy is under 500, do the big exploration, which aims to escape from the
 * local optimal. If within 10 times' feasible exploring iterations, there is no better
 * solution can be found, jump out the exploring, else do the crossover to the better solution,
 * if the best time found so far under 210.0 seconds, we will fix the strategy and do 20
 * times' feasible mutation to the pacing array to locate the local optimal. if can not
 * find the better one, we will fix the pacing and do 10 times' feasible mutation to the
 * strategy array to locate the local optimal.
 * Further more,)we can adjust the pacing and strategy arrays according to the remaining
 * energy of corresponding player (not implemented yet in this code).
 */
package ev;
import java.util.ArrayList;
import java.util.Random;
import ev.initial.Individual;
import ev.initial.InitialMenSetUp1;
import ev.operator.Crossover;
import ev.operator.MidCycle;
import ev.operator.Mutation;
import ev.operator.Swap;
import ev.selection.NewMenSimpleSelection;
import ev.selection.Selection;
import ev.selection.SimpleSelection;

import TeamPursuit.*;

public class EA_Team_Men3 implements Team_Men {

	public void emulation() {
		SimulationResult result = null;
        MensTeamPursuit mensTeamPursuit = new MensTeamPursuit();

		//initial population whose size is three
        new InitialMenSetUp1();
        ArrayList<Individual> p=InitialMenSetUp1.data;
        Selection s=new SimpleSelection();
        Selection ns=new NewMenSimpleSelection();
        p=s.select(p,10);
		int times=3000;
		int matingTimes=3;
		Mutation m=new Swap();
		Crossover c=new MidCycle();
		Random r=new Random();
		int count=0;
		double oldTime;
		while(times>0){
			System.out.println("times= "+times);
			oldTime=p.get(0).getTime();
			//Do the crossover operation to the first two solutions
			for(int i=0;i<matingTimes;i++){
				Individual p1=p.get(0).copy();
				Individual p2=p.get(1).copy();
				boolean[] a=c.cross(p1.getStrategy(), p2.getStrategy());
				int[] b=c.cross(p1.getPacing(), p2.getPacing());
				Individual newIndiv=new Individual(a,b);
				try {
	        		result = mensTeamPursuit.simulate(a, b);
				} catch (Exception e) {
					e.printStackTrace();
				}
				if(!isValid(result)){i--;}
				else{
					newIndiv.setTime(result.getFinishTime());
					p.add(newIndiv);
					//System.out.println("p.sizeC1= "+p.size());
				}
			}

			//Do the crossover operation to the random two solutions
			for(int i=0;i<matingTimes;i++){
				Individual p4=p.get(r.nextInt(10)).copy();
				Individual p5=p.get(r.nextInt(10)).copy();
				boolean[] d=c.cross(p4.getStrategy(), p5.getStrategy());
				int[] e=c.cross(p4.getPacing(), p5.getPacing());
				Individual newIndiv=new Individual(d,e);
				try {
	        		result = mensTeamPursuit.simulate(d, e);
				} catch (Exception e1) {
					e1.printStackTrace();
				}
				if(!isValid(result)){i--;}
				else{
					newIndiv.setTime(result.getFinishTime());
					p.add(newIndiv);
				}
				//System.out.println("p.sizeC2= "+p.size());
			}

			//Do the mutation operation to the third solutions
			for(int i=0;i<matingTimes;i++){
				Individual p3=p.get(2).copy();
				boolean[] ma=m.mutate(p3.getStrategy());
				int[] mb=m.mutate(p3.getPacing());
				Individual newIndiv=new Individual(ma,mb);
				try {
	        		result = mensTeamPursuit.simulate(ma, mb);
				} catch (Exception e) {
					e.printStackTrace();
				}
				if(!isValid(result)){i--;}
				else{
					newIndiv.setTime(result.getFinishTime());
					p.add(newIndiv);
				}

				//System.out.println("p.sizeM= "+p.size());
			}
			//System.out.println("p.sizeM= "+p.size());
			p=s.select(p, 10);
			try {
        		result = mensTeamPursuit.simulate(p.get(0).getStrategy(), p.get(0).getPacing());
			} catch (Exception e) {
				e.printStackTrace();
			}

			if(p.get(0).getTime()==oldTime){
				count++;
			}else{
				count=0;
			}
			if(count==10){
				System.out.println("adding new individual");
				p=ns.select(p, 10);
			}


			for(int i=0;i<p.size();i++){
				System.out.println(p.get(i).toString());
			}
			System.out.println(result);
			times--;
		}
		System.out.println("-----------------------------");
		System.out.println(p.get(0));
	}

	private boolean isValid(SimulationResult result){
		if(result.getProportionCompleted() < 0.9999998){
			return false;
		}else{
			return true;
		}
	}


}